home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 8 / QRZ Ham Radio Callsign Database - Volume 8.iso / pc / files / t_unix / j109lxa4.tar / ftpsubr.c < prev    next >
C/C++ Source or Header  |  1994-06-04  |  4KB  |  231 lines

  1. /* Routines common to both the FTP client and server
  2.  * Copyright 1991 Phil Karn, KA9Q
  3.  */
  4.  /* Mods by G1EMM */
  5. #include <stdio.h>
  6. #include "global.h"
  7. #include "mbuf.h"
  8. #include "socket.h"
  9. #include "proc.h"
  10. #include "ftp.h"
  11. #include "ftpcli.h"
  12.  
  13. /* Send a file (opened by caller) on a network socket.
  14.  * Normal return: count of bytes sent
  15.  * Error return: -1
  16.  */
  17. long
  18. sendfile(fp,s,mode,hash)
  19. FILE *fp;    /* File to be sent */
  20. int s;        /* Socket to be sent on */
  21. int mode;    /* Transfer mode */
  22. int hash;    /* Print hash marks every BLKSIZE bytes */
  23. {
  24.     register struct mbuf *bp;
  25.     int c,oldf;
  26.     long total = 0;
  27.     long hmark = 0;
  28.  
  29.     switch(mode){
  30.     default:
  31.     case LOGICAL_TYPE:
  32.     case IMAGE_TYPE:
  33.         sockmode(s,SOCK_BINARY);
  34.         for(;;){
  35.             bp = ambufw(BLKSIZE);
  36.             if((bp->cnt = fread(bp->data,1,BLKSIZE,fp)) == 0){
  37.                 free_p(bp);
  38.                 break;
  39.             }
  40.             total += bp->cnt;
  41.             if(send_mbuf(s,bp,0,NULLCHAR,0) == -1){
  42.                 total = -1;
  43.                 break;
  44.             }
  45.             while(hash == V_HASH && total >= hmark+1000){
  46.                 tputc('#');
  47.                 hmark += 1000;
  48.             }
  49.             while(hash == V_BYTE && total >= hmark+1000){
  50.                 tprintf("Bytes sent : %ld\r", total);
  51.                 hmark += 1000;
  52.             }
  53.         }
  54.         break;
  55.     case ASCII_TYPE:
  56.         oldf = setflush(s,-1);
  57.         /* Let the newline mapping code in usputc() do the work */
  58.         sockmode(s,SOCK_ASCII);
  59.         while((c = getc(fp)) != EOF){
  60. #if !defined(UNIX) && !defined(__TURBOC__)
  61.             if(c == '\r'){
  62.                 /* Needed only if the OS uses a CR/LF
  63.                  * convention and getc doesn't do
  64.                  * an automatic translation
  65.                  */
  66.                 continue;
  67.             }
  68. #endif
  69.             if(usputc(s,(char)c) == -1){
  70.                 total = -1;
  71.                 break;
  72.             }
  73.             total++;
  74.             while(hash == V_HASH && total >= hmark+1000){
  75.                 tputc('#');
  76.                 hmark += 1000;
  77.             }
  78.             while(hash == V_BYTE && total >= hmark+1000){
  79.                 tprintf("Bytes sent : %ld\r", total);
  80.                 hmark += 1000;
  81.             }
  82.         }
  83.         usflush(s);
  84.         setflush(s,oldf);        
  85.         break;
  86.     }
  87.     if(hash)
  88.         tputc('\n');
  89.     return total;
  90. }
  91. /* Receive a file (opened by caller) from a network socket.
  92.  * Normal return: count of bytes received
  93.  * Error return: -1
  94.  */
  95. long
  96. recvfile(fp,s,mode,hash)
  97. FILE *fp;
  98. int s;
  99. int mode;
  100. int hash;
  101. {
  102.     int cnt,c;
  103.     struct mbuf *bp;
  104.     long total = 0;
  105.     long hmark = 0;
  106.  
  107.     switch(mode){
  108.     default:
  109.     case LOGICAL_TYPE:
  110.     case IMAGE_TYPE:
  111.         sockmode(s,SOCK_BINARY);
  112.         while((cnt = recv_mbuf(s,&bp,0,NULLCHAR,0)) != 0){
  113.             if(cnt == -1){
  114.                 total = -1;
  115.                 break;
  116.             }
  117.             total += cnt;
  118.             while(hash == V_HASH && total >= hmark+1000){
  119.                 tputc('#');
  120.                 hmark += 1000;
  121.             }
  122.             while(hash == V_BYTE && total >= hmark+1000){
  123.                 tprintf("Bytes recv : %ld\r", total);
  124.                 hmark += 1000;
  125.             }
  126.             if(fp != NULLFILE){
  127.                 if(write_p(fp,bp) == -1){
  128.                     free_p(bp);
  129.                     total = -1;
  130.                     break;
  131.                 }
  132.                 free_p(bp);
  133.             } else {
  134.                 send_mbuf(Curproc->output, bp, 0, NULLCHAR, 0);
  135.             }
  136.         }
  137.         break;
  138.     case ASCII_TYPE:
  139.         sockmode(s,SOCK_ASCII);
  140.         while((c = recvchar(s)) != EOF){
  141.             if(fp != NULLFILE){
  142. #if !defined(UNIX) && !defined(__TURBOC__) && !defined(AMIGA)
  143.                 if(c == '\n'){
  144.                     /* Needed only if the OS uses a CR/LF
  145.                      * convention and putc doesn't do
  146.                      * an automatic translation
  147.                      */
  148.                     putc('\r',fp);
  149.                 }
  150. #endif
  151.                 if(putc(c,fp) == EOF){
  152.                     total = -1;
  153.                     break;
  154.                 }
  155.             } else {
  156.                 tputc((char)c);
  157.             }
  158.             total++;
  159.             while(hash == V_HASH && total >= hmark+1000){
  160.                 tputc('#');
  161.                 hmark += 1000;
  162.             }
  163.             while(hash == V_BYTE && total >= hmark+1000){
  164.                 tprintf("Bytes recv : %ld\r", total);
  165.                 hmark += 1000;
  166.             }
  167.         }
  168.         /* Detect an abnormal close */
  169.         if(socklen(s,0) == -1)
  170.             total = -1;
  171.         break;
  172.     }
  173.     if(hash)
  174.         tputc('\n');
  175.     return total;
  176. }
  177. /* Determine if a file appears to be binary (i.e., non-text).
  178.  * Return 1 if binary, 0 if ascii text after rewinding the file pointer.
  179.  *
  180.  * Used by FTP to warn users when transferring a binary file in text mode.
  181.  */
  182. int
  183. isbinary(fp)
  184. FILE *fp;
  185. {
  186.     int c,i;
  187.     int rval;
  188.  
  189.     rval = 0;
  190.     for(i=0;i<512;i++){
  191.         if((c = getc(fp)) == EOF)
  192.             break;
  193.         if(c & 0x80){
  194.             /* High bit is set, probably not text */
  195.             rval = 1;
  196.             break;
  197.         }
  198.     }
  199.     /* Assume it was at beginning */
  200.     fseek(fp,0L,SEEK_SET);
  201.     return rval;
  202. }
  203.  
  204. long
  205. getsize(fp)
  206. FILE *fp;
  207. {
  208.     fseek(fp,0L,SEEK_END);    /* Go to end of file */
  209.     return ftell(fp);    /* Return file pointer position */
  210. }
  211.  
  212. /* Compute checksum of the first n bytes */
  213. unsigned long
  214. checksum(fp,n)
  215. FILE *fp;
  216. long n;
  217. {
  218.     unsigned long sum;
  219.     long i;
  220.     int c;
  221.  
  222.     rewind(fp);
  223.     sum = 0;
  224.     for(i=1;i<=n;i++){
  225.         if((c = fgetc(fp)) == EOF)
  226.             break;
  227.         sum += (unsigned long)c;
  228.     }
  229.     return sum;
  230. }
  231.